home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / NR4USER.C < prev    next >
Text File  |  1993-08-09  |  5KB  |  232 lines

  1. /* net/rom level 4 (transport) protocol user level calls
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "config.h"
  9. #ifdef NETROM
  10. #include "mbuf.h"
  11. #include "timer.h"
  12. #include "ax25.h"
  13. #include "netrom.h"
  14. #include "nr4.h"
  15. #include <ctype.h>
  16.  
  17. #undef NR4DEBUG
  18.  
  19. /* Open a NET/ROM transport connection */
  20. struct nr4cb *
  21. open_nr4(local,remote,mode,r_upcall,t_upcall,s_upcall,user)
  22. struct nr4_addr *local ;    /* local node address */
  23. struct nr4_addr *remote ;    /* destination node address */
  24. int mode ;            /* active/passive/server */
  25. void (*r_upcall)() ;        /* received data upcall */
  26. void (*t_upcall)() ;        /* transmit upcall */
  27. void (*s_upcall)() ;        /* state change upcall */
  28. int user ;            /* user linkage area */
  29. {
  30.     struct nr4cb *cb ;
  31.     struct nr4hdr hdr ;
  32.     struct nr4_addr nr4tmp;
  33.  
  34.     if ((cb = new_n4circ()) == NULLNR4CB)
  35.         return NULLNR4CB ;        /* No circuits available */
  36.  
  37.     if(remote == NULLNRADDR){
  38.         remote = &nr4tmp;
  39.         setcall(remote->user," ");
  40.         setcall(remote->node," ");
  41.     }
  42.     
  43.     /* Stuff what info we can into control block */
  44.  
  45.     ASSIGN(cb->remote,*remote) ;
  46.     /* Save local address for connect retries */
  47.     ASSIGN(cb->local,*local) ;
  48.  
  49.     cb->r_upcall = r_upcall ;
  50.     cb->t_upcall = t_upcall ;
  51.     cb->s_upcall = s_upcall ;
  52.     cb->user = user ;
  53.     cb->clone = 0 ;
  54.  
  55.     switch(mode){
  56.     case AX_SERVER:
  57.         cb->clone = 1;
  58.     case AX_PASSIVE:    /* Note fall-thru */
  59.         cb->state = NR4STLISTEN;
  60.         return cb;
  61.     case AX_ACTIVE:
  62.         break;
  63.     }    
  64.     /* Format connect request header */
  65.  
  66.     hdr.opcode = NR4OPCONRQ ;
  67.     hdr.u.conreq.myindex = cb->mynum ;
  68.     hdr.u.conreq.myid = cb->myid ;
  69.     hdr.u.conreq.window = Nr4window ;
  70.     memcpy(hdr.u.conreq.user,local->user,AXALEN);
  71.  
  72.     /* If I have a unique callsign per interface, then a layer violation */
  73.     /* will be required to determine the "real" callsign for my */
  74.     /* (virtual) node.  This suggests that callsign-per-interface is not */
  75.     /* desirable, which answers *that* particular open question. */
  76.     
  77.     memcpy(hdr.u.conreq.node,local->node,AXALEN);
  78.  
  79.     /* Set and start connection retry timer */
  80.  
  81.     cb->cdtries = 1 ;
  82.     cb->srtt = Nr4irtt * 1000 ;
  83.     set_timer(&cb->tcd,cb->srtt);
  84.     cb->tcd.func = nr4cdtimeout ;
  85.     cb->tcd.arg = cb ;
  86.     start_timer(&cb->tcd) ;
  87.  
  88.     /* Send connect request packet */
  89.  
  90.     nr4sframe(remote->node,&hdr,NULLBUF) ;
  91.  
  92.     /* Set up initial state and signal state change */
  93.  
  94.     cb->state = NR4STDISC ;
  95.     nr4state(cb, NR4STCPEND) ;
  96.  
  97.     /* Return control block address */
  98.  
  99.     return cb ;
  100. }
  101.  
  102. /* Send a net/rom transport data packet */
  103. int
  104. send_nr4(cb,bp)
  105. struct nr4cb *cb ;
  106. struct mbuf *bp ;
  107. {
  108.     if (cb == NULLNR4CB || bp == NULLBUF)
  109.         return -1 ;
  110.     enqueue(&cb->txq,bp) ;
  111.     return nr4output(cb) ;
  112. }
  113.  
  114. /* Receive incoming net/rom transport data */
  115. struct mbuf *
  116. recv_nr4(cb,cnt)
  117. struct nr4cb *cb ;
  118. int16 cnt ;
  119. {
  120.     struct mbuf *bp ;
  121.  
  122.     if (cb->rxq == NULLBUF)
  123.         return NULLBUF ;
  124.  
  125.     if (cnt == 0) {
  126.         bp = cb->rxq ;            /* Just give `em everything */
  127.         cb->rxq = NULLBUF ;
  128.     }
  129.     else {
  130.         bp = alloc_mbuf(cnt);
  131.         bp->cnt = pullup(&cb->rxq,bp->data,cnt);
  132.     }
  133.     /* If this has un-choked us, reopen the window */
  134.     if (cb->qfull && len_p(cb->rxq) < Nr4qlimit) {
  135.         cb->qfull = 0 ;                /* Choke flag off */
  136.         nr4ackit(cb) ;        /* Get things rolling again */
  137.     }
  138.  
  139.     return bp ;
  140. }
  141.  
  142. /* Close a NET/ROM connection */
  143. void
  144. disc_nr4(cb)
  145. struct nr4cb *cb ;
  146. {
  147.     struct nr4hdr hdr ;
  148.  
  149.     if(!nr4valcb(cb))
  150.         return;
  151.  
  152.     if (cb->state == NR4STLISTEN) {
  153.         free_n4circ(cb);
  154.         return;
  155.     }
  156.     if (cb->state != NR4STCON) {
  157.         reset_nr4(cb);
  158.         return ;
  159.     }
  160.     /* Format disconnect request packet */
  161.     
  162.     hdr.opcode = NR4OPDISRQ ;
  163.     hdr.yourindex = cb->yournum ;
  164.     hdr.yourid = cb->yourid ;
  165.  
  166.     /* Set and start timer */
  167.     
  168.     cb->cdtries = 1 ;
  169.     set_timer(&cb->tcd,2 * cb->srtt);
  170.     cb->tcd.func = nr4cdtimeout ;
  171.     cb->tcd.arg = cb ;
  172.     start_timer(&cb->tcd) ;
  173.  
  174.     /* Send packet */
  175.  
  176.     nr4sframe(cb->remote.node, &hdr, NULLBUF) ;
  177.  
  178.     /* Signal state change.  nr4state will take care of stopping */
  179.     /* the appropriate timers and resetting window pointers. */
  180.  
  181.     nr4state(cb, NR4STDPEND) ;
  182.  
  183. }
  184.  
  185. /* Abruptly terminate a NET/ROM transport connection */
  186. void
  187. reset_nr4(cb)
  188. struct nr4cb *cb ;
  189. {
  190.     if(!nr4valcb(cb))
  191.         return;
  192.  
  193.     cb->dreason = NR4RRESET ;
  194.     nr4state(cb,NR4STDISC) ;
  195. }
  196.  
  197.  
  198. /* Force retransmission on a NET/ROM transport connection */
  199. int
  200. kick_nr4(cb)
  201. struct nr4cb *cb ;
  202. {
  203.     unsigned seq ;
  204.     struct timer *t ;
  205.  
  206.     if(!nr4valcb(cb))
  207.         return -1 ;
  208.  
  209.     switch (cb->state) {
  210.       case NR4STCPEND:
  211.       case NR4STDPEND:
  212.           stop_timer(&cb->tcd) ;
  213.         nr4cdtimeout(cb) ;
  214.         break ;
  215.  
  216.       case NR4STCON:
  217.         if (cb->nextosend != cb->ackxpected) {    /* if send window is open: */
  218.             for (seq = cb->ackxpected ;
  219.                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  220.                  seq = (seq + 1) & NR4SEQMASK) {
  221.                 t = &cb->txbufs[seq % cb->window].tretry ;
  222.                 stop_timer(t) ;
  223.                 t->state = TIMER_EXPIRE ;    /* fool retry routine */
  224.             }
  225.             nr4txtimeout(cb) ;
  226.         }
  227.         break ;
  228.     }
  229.  
  230.     return 0 ;
  231. }
  232. #endif /* NETROM */